package filemanager;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import utility.Utility;
import core.Client;
import core.NetProtocoll;
import dbms.DBParameters;

public class FileTransferClientSocket{

	String mainDir;

	Socket client;

	ObjectOutputStream out;
	ObjectInputStream in;
	
	protected boolean isReady;

	public FileTransferClientSocket()
	{
		try {
			this.isReady = false;
			
			this.mainDir = Client.getInstance().getConfigs().get(DBParameters.MAINDIR);
			
			this.client = new Socket(Client.getInstance().getServerIP(), 8000);
	
			this.out = new ObjectOutputStream(this.client.getOutputStream());
			this.out.flush();
			this.in = new ObjectInputStream(this.client.getInputStream());
			
			Utility.sendSocketMessage(NetProtocoll.USERID + Client.getInstance().getUserId(), this.out);

			if(!Utility.readSocketMessage(this.in).equals(NetProtocoll.USERIDOK))
				return;
			//this.getFile(Utility.readSocketMessage(this.in));
			
			//this.start();
			
			this.isReady = true;
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	/*
	@Override
	public void run() {

		String message = Utility.readSocketMessage(this.in);
		
		while(!message.equals(NetProtocoll.BYE))
		{
			if(message.startsWith(NetProtocoll.STARTFILESENDING))
				this.getFile(message);
			
			message = Utility.readSocketMessage(this.in);
		}
		
	}
	
	protected void getFile(String message)
	{
		System.out.println("RICEVO UN FILE !!! " + message);
		
		try {
		    long start = System.currentTimeMillis();
			
			String []parameter = message.substring(NetProtocoll.STARTFILESENDING.length()).split(";");
			
			String fileName = parameter[0];
			int fileSize = Integer.parseInt(parameter[1]);
			
			int bytesRead;
			int current = 0;
			
			FileOutputStream fos;
			fos = new FileOutputStream("/home/neb/workspace/openLAVMClient/" + fileName);
	
			byte [] mybytearray  = new byte [fileSize];
	
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			bytesRead = this.in.read(mybytearray, 0, mybytearray.length);
			current = bytesRead;
	
			do {
			   bytesRead = this.in.read(mybytearray, current, (mybytearray.length-current));
			   if(bytesRead >= 0) current += bytesRead;
			} while(bytesRead > -1);
	
			bos.write(mybytearray, 0 , current);
			bos.flush();
			
			long end = System.currentTimeMillis();
			long time = end - start;
			System.out.println("TEMPO DI TRASFERIMENTO: " + time);
			
			bos.close();

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}*/
	
	public boolean getFile()
	{
		try {
			
			String message = Utility.readSocketMessage(this.in);
			
			System.out.println("RICEVO UN FILE !!! " + message);
			
		    long start = System.currentTimeMillis();
			
			String []parameter = message.substring(NetProtocoll.STARTFILESENDING.length()).split(";");		
			String programName = parameter[0];
			String fileName = parameter[1];
			int fileSize = Integer.parseInt(parameter[2]);
			
			DataOutputStream output;

			BufferedInputStream bis;
			BufferedOutputStream bos;

			byte[] receivedData;
			int in;
			output = new DataOutputStream (this.client.getOutputStream() );
		
			//output.writeUTF("ack 1");

			File dir = new File(this.mainDir + "/" + programName);
			if(!dir.exists())
				dir.mkdir();
			
			receivedData = new byte[1024];
			bis = new BufferedInputStream(this.client.getInputStream());
			bos = new BufferedOutputStream(new FileOutputStream(this.mainDir + "/" + programName  + "/" + fileName));
			
			
			while ((in = bis.read(receivedData)) != -1)
				bos.write(receivedData,0,in);
			
			bos.flush();
			
			bis.close();
			bos.close();
			this.client.close();
			
			long end = System.currentTimeMillis();
			long time = end - start;
			System.out.println("TEMPO DI TRASFERIMENTO: " + time);
			
			return true;
		} catch (IOException e) {

			try {
				this.client.close();
			} catch (IOException e1) {}

			return false;
		}
	}
	
	public boolean sendFile(String programName, String fileName, String extenzion)
	{
		try {
	
			File file = new File(this.mainDir + "/" + programName + "/" + fileName + "." + extenzion);

			int fileSize = (int)file.length();
			
			String msg = NetProtocoll.STARTFILESENDING;
			msg += programName  + ";";
			msg += fileName + "." + extenzion + ";";
			msg += String.valueOf(fileSize);
			
			Utility.sendSocketMessage(msg, this.out);
			
			DataInputStream input;

			BufferedInputStream bis;
			BufferedOutputStream bos;
			int in;
			byte[] byteArray;

			input = new DataInputStream (this.client.getInputStream());
			//System.out.println("Server message: " + input.readUTF());

			//bis = new BufferedInputStream(new FileInputStream("encryptAtmMsg.txt"));
			bis = new BufferedInputStream(new FileInputStream(file));
			bos = new BufferedOutputStream(this.client.getOutputStream());
			
			byteArray = new byte[8192];
			
			while ((in = bis.read(byteArray)) != -1)
				bos.write(byteArray,0,in);
			
			bos.flush();
			
			bis.close();
			bos.close();
			
			this.client.close();

			return true;
		} catch (IOException e) {
			try {
				this.client.close();
			} catch (IOException e1){}
			
			return false;
		}	
	}

	public boolean isReady(){ return this.isReady; }
}
